package com.project.service.impl;

import com.project.model.entity.Module;
import com.project.model.entity.ProjectReport;
import com.project.model.entity.ReportContent;
import com.project.model.entity.SubSystem;
import com.project.service.*;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

import static com.project.model.constant.Minio.*;
import static com.project.model.constant.Minio.BUCKET_NAME;

@Service
public class ExportServiceImpl  implements ExportService {

    @Autowired
    private ProjectReportService projectReportService;

    @Autowired
    private ReportContentService reportContentService;

    @Autowired
    private SubSystemService subSystemService;

    @Autowired
    private ModuleService moduleService;

    //content --> word下载
    @Override
    public XWPFDocument exportReportDateWord(String reportId) {
        Integer id = Integer.valueOf(reportId);
        ProjectReport projectReport = projectReportService.getProjectReportByReportId(id);
        List<ReportContent> reportContents = reportContentService.getReportContentsByReportId(projectReport.getReportId());
        List<SubSystem> subSystems = subSystemService.getSubSystemsByReportId(projectReport.getReportId());
        List<Module> modules = new ArrayList<>();
        for (SubSystem sub : subSystems) {
            List<Module> moduleTemps = moduleService.getModulesBySubsystemId(sub.getId());
            for (Module temp : moduleTemps) {
                modules.add(temp);
            }
        }

        XWPFDocument document = null;
        try (FileInputStream fis = new FileInputStream("src/main/resources/template/template.docx")) {
            document = new XWPFDocument(fis);

            // 替换文本中的占位符
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                for (XWPFRun run : paragraph.getRuns()) {
                    String text = run.getText(0);
                    if (text != null) {
                        text = text.replace("reportName", projectReport.getReportName())
                                .replace("companyName", projectReport.getCompanyName())
                                .replace("companyLocation", projectReport.getCompanyLocation())
                                .replace("evaluateTime", projectReport.getEvaluateTime())
                                .replace("reportDescription", projectReport.getReportDescription())
                                .replace("softwareType", projectReport.getSoftwareType())
                                .replace("factorNum", String.valueOf(projectReport.getFactorNum()))
                                .replace("factorStage", projectReport.getFactorStage());
                        run.setText(text, 0);
                    }
                }
            }

            // 填充第一个表格
            XWPFTable firstTable = document.getTableArray(0);
            if (firstTable != null && firstTable.getNumberOfRows() >= 2) {
                XWPFTableRow headerRow = firstTable.getRow(0);
                XWPFTableRow percentageRow = firstTable.getRow(1);
                for (ReportContent reportContent : reportContents) {
                    for (int j = 1; j < headerRow.getTableCells().size(); j++) {
                        XWPFTableCell headerCell = headerRow.getCell(j);
                        if (headerCell != null) {
                            String headerText = headerCell.getText();
                            if (headerText != null && headerText.trim().equals(reportContent.getStage())) {
                                XWPFTableCell percentageCell = percentageRow.getCell(j);
                                if (percentageCell != null) {
                                    percentageCell.setText(reportContent.getPercentage() + "%");
                                    XWPFParagraph paragraph = percentageCell.getParagraphs().get(0);
                                    paragraph.setAlignment(ParagraphAlignment.CENTER);
                                    paragraph.setVerticalAlignment(TextAlignment.CENTER);
                                }
                                break;
                            }
                        }
                    }
                }
            }

            // 填充第二个表格
            XWPFTable secondTable = document.getTableArray(1);
            for (int i = 0; i < subSystems.size(); i++) {
                XWPFTableRow row = secondTable.createRow();
                SubSystem subSystem = subSystems.get(i);
                row.getCell(0).setText(subSystem.getName());
                row.getCell(1).setText(subSystem.getWorkload());
                row.getCell(2).setText(String.valueOf(subSystem.getDeveloperNum()));
                row.getCell(3).setText(subSystem.getExpense().toString());
                row.getCell(4).setText(subSystem.getExpenseRatio() + "%");
                for (XWPFTableCell cell : row.getTableCells()) {
                    XWPFParagraph paragraph = cell.getParagraphs().get(0);
                    paragraph.setAlignment(ParagraphAlignment.CENTER);
                    paragraph.setVerticalAlignment(TextAlignment.CENTER);
                }
            }

            // 填充第三个表格
            XWPFTable thirdTable = document.getTableArray(2);
            for (int i = 0; i < modules.size(); i++) {
                XWPFTableRow row = thirdTable.createRow();
                Module module = modules.get(i);
                row.getCell(0).setText(String.valueOf(module.getSubsystemId()));
                row.getCell(1).setText(module.getName());
                row.getCell(2).setText(module.getFunctionType());
                row.getCell(3).setText(String.valueOf(module.getFunctionPointNum()));
                row.getCell(4).setText(String.valueOf(module.getUfp()));
                row.getCell(5).setText(module.getReuseLevel());
                for (XWPFTableCell cell : row.getTableCells()) {
                    XWPFParagraph paragraph = cell.getParagraphs().get(0);
                    paragraph.setAlignment(ParagraphAlignment.CENTER);
                    paragraph.setVerticalAlignment(TextAlignment.CENTER);
                }
            }

            // 子系统模块描述
            for (int i = 0; i < document.getParagraphs().size(); i++) {
                XWPFParagraph paragraph = document.getParagraphs().get(i);
                if (paragraph.getText().contains("功能点明细")) {
                    XWPFParagraph insertParagraph = document.insertNewParagraph(paragraph.getCTP().newCursor());
                    insertParagraph.setPageBreak(false);
                    XWPFRun spaceRun = insertParagraph.createRun();
                    spaceRun.addBreak();

                    for (Module module : modules) {
                        XWPFParagraph moduleParagraph = document.insertNewParagraph(insertParagraph.getCTP().newCursor());
                        moduleParagraph.setStyle("2");
                        XWPFRun runName = moduleParagraph.createRun();
                        runName.setText(module.getName());

                        XWPFParagraph moduleParagraph2 = document.insertNewParagraph(insertParagraph.getCTP().newCursor());
                        moduleParagraph2.setStyle("0");
                        XWPFRun runDes = moduleParagraph2.createRun();
                        runDes.setText(module.getDescription());
                    }
                    break;
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return document;
    }

    @Override
    public void exportReportDatePdf(String reportId) {

    }

    public void upload(XWPFDocument document,String id){
        try {
            // 创建 MinIO 客户端
            MinioClient minioClient = MinioClient.builder()
                    .endpoint(MINIO_IP) // 替换为 MinIO 服务器 URL
                    .credentials(MINIO_ACCOUNT, MINIO_PASSWORD)
                    .build();


            // 将 XWPFDocument 写入 ByteArrayOutputStream
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            document.write(byteArrayOutputStream);

            // 将 ByteArrayOutputStream 转换为 InputStream
            byte[] documentBytes = byteArrayOutputStream.toByteArray();
            ByteArrayInputStream inputStream = new ByteArrayInputStream(documentBytes);

            // 上传到 MinIO
            String bucketName = BUCKET_NAME;
            ProjectReport projectReport = projectReportService.getProjectReportById(Integer.valueOf(id));
            String objectName = "Report_" +projectReport.getReportName()+"_"+ System.currentTimeMillis() + ".docx";


            String reportUrl = MINIO_IP + BUCKET_NAME +"/"+ objectName;
            //写入对应的Report_url

            projectReport.setReportUrl(reportUrl);
            projectReportService.updateProjectReport(projectReport);

            // 检查存储桶是否存在
            BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build();
            if (!minioClient.bucketExists(bucketExistsArgs)) {
                // 使用 MakeBucketArgs 创建存储桶
                MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();
                minioClient.makeBucket(makeBucketArgs);
            }

            // 上传文件
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .stream(inputStream, documentBytes.length, -1)
                            .contentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document")
                            .build()
            );

            System.out.println("文件上传成功到 MinIO：" + objectName);
            inputStream.close(); // 关闭输入流以释放资源

        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("上传文件到 MinIO 时出错：" + e.getMessage());
        }
    }

    
}
